package com.eagle.roomsearch.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * 日期时间处理工具类
 *
 * @author Jetvin
 * @version ╮(╯▽╰)╭
 * @date 2018/1/11
 * @time 15:15
 * @modify by
 */
public class DateUtil {

    private static LocalDate localDate; //日期

    private static LocalTime localTime; //时间

    private static LocalDateTime localDateTime; //日期时间

    private static DateTimeFormatter formatter;

    //用作获取星期的开始时间与结束时间
    private final static int[] PLUS = {0, 5, 4, 3, 2, 1, 0, 6};
    private final static int[] MINUS = {0, 1, 2, 3, 4, 5, 6, 0};

    public static String getFirstOfWeek(String date, String format) {

        formatter = DateTimeFormatter.ofPattern(format);
        localDate = LocalDate.parse(date, formatter);

        return localDate.minusDays(MINUS[DayOfWeek.from(localDate).getValue()]).format(formatter);
    }

    public static LocalDate getFirstOfWeek(LocalDate localDate) {

        return localDate.minusDays(MINUS[DayOfWeek.from(localDate).getValue()]);
    }

    public static String getLastOfWeek(String date, String format) {

        formatter = DateTimeFormatter.ofPattern(format);
        localDate = LocalDate.parse(date, formatter);

        return localDate.plusDays(PLUS[DayOfWeek.from(localDate).getValue()]).format(formatter);
    }

    public static LocalDate getLastOfWeek(LocalDate localDate) {

        return localDate.plusDays(PLUS[DayOfWeek.from(localDate).getValue()]);
    }

    public static int getLengthOfMonth(String date, String format) {

        formatter = DateTimeFormatter.ofPattern(format);
        localDate = LocalDate.parse(date, formatter);

        return localDate.lengthOfMonth();
    }

    public static int getLengthOfYear(String date, String format) {

        formatter = DateTimeFormatter.ofPattern(format);
        localDate = LocalDate.parse(date, formatter);

        return localDate.lengthOfYear();
    }

    public static String getStartDateWithPage(int pageNum, int pageSize, String format) {
        formatter = DateTimeFormatter.ofPattern(format);
        localDate = LocalDate.now();
        localDate = localDate.minusDays(((pageNum - 1) * pageSize) + (pageSize - 1));

        return localDate.format(formatter);
    }

    public static String getEndDateWithPage(int pageNum, int pageSize, String format) {
        formatter = DateTimeFormatter.ofPattern(format);
        localDate = LocalDate.now();
        localDate = localDate.minusDays(((pageNum - 1) * pageSize));

        return localDate.format(formatter);
    }

    public static String getStartDateTimeWithPage(int pageNum, int pageSize, String format) {
        formatter = DateTimeFormatter.ofPattern(format);
        localDateTime = LocalDateTime.now();
        localDateTime = localDateTime.minusDays(((pageNum - 1) * pageSize) + (pageSize - 1));
        localDateTime = localDateTime.withHour(0);
        localDateTime = localDateTime.withMinute(0);
        localDateTime = localDateTime.withSecond(0);
        localDateTime = localDateTime.withNano(0);

        return localDateTime.format(formatter);
    }

    public static String getEndDateTimeWithPage(int pageNum, int pageSize, String format) {
        formatter = DateTimeFormatter.ofPattern(format);
        localDateTime = LocalDateTime.now();
        localDateTime = localDateTime.minusDays(((pageNum - 1) * pageSize));
        localDateTime = localDateTime.withHour(23);
        localDateTime = localDateTime.withMinute(59);
        localDateTime = localDateTime.withSecond(59);
        localDateTime = localDateTime.withNano(999);

        return localDateTime.format(formatter);
    }

    public static List<String> getHourGroup(int space, String separator, String format) {
        formatter = DateTimeFormatter.ofPattern(format);
        List<String> hourGroup = new ArrayList<>();
        StringBuilder hour = new StringBuilder();
        int length = 24 / space;
        for (int i = 0; i < length; i++) {
            localTime = LocalTime.of(i * space, 0, 0, 0);
            hour.append(localTime.format(formatter));
            hour.append(separator);
            localTime = LocalTime.of(i * space + (space - 1), 59, 59, 999);
            hour.append(localTime.format(formatter));

            hourGroup.add(hour.toString());
            hour.setLength(0);
        }

        return hourGroup;
    }

    public static List<String> getDayGroup(int space, String separator, String start, String end, String format) {
        formatter = DateTimeFormatter.ofPattern(format);
        List<String> dayGroup = new ArrayList<>();
        StringBuilder day = new StringBuilder();

        LocalDate startDate = LocalDate.parse(start, formatter);
        LocalDate endDate = LocalDate.parse(end, formatter);

        while (startDate.compareTo(endDate) <= 0) {

            day.append(startDate.format(formatter));

            if (space != 1 && startDate.plusDays(space - 1).compareTo(endDate) <= 0) {
                day.append(separator);
                day.append(startDate.plusDays(space - 1).format(formatter));
            } else if (space != 1 && startDate.plusDays(space - 1).compareTo(endDate) > 1) {
                day.append(separator);
                day.append(endDate.format(formatter));
            }

            dayGroup.add(day.toString());
            startDate = startDate.plusDays(space);
            day.setLength(0);
        }

        return dayGroup;
    }

    public static List<String> getMonthGroup(int space, String separator, String start, String end, String format) {
        formatter = DateTimeFormatter.ofPattern(format);
        List<String> monthGroup = new ArrayList<>();
        StringBuilder month = new StringBuilder();

        LocalDate startDate = LocalDate.parse(start, formatter);
        LocalDate endDate = LocalDate.parse(end, formatter);

        formatter = DateTimeFormatter.ofPattern(format.substring(0, 7));
        while (startDate.compareTo(endDate) <= 0) {

            month.append(startDate.format(formatter));

            if (space != 1 && startDate.plusMonths(space - 1).compareTo(endDate) <= 0) {
                month.append(separator);
                month.append(startDate.plusMonths(space - 1).format(formatter));
            } else if (space != 1 && startDate.plusMonths(space - 1).compareTo(endDate) > 1) {
                month.append(separator);
                month.append(endDate.format(formatter));
            }

            monthGroup.add(month.toString());
            startDate = startDate.plusMonths(space);
            month.setLength(0);
        }

        return monthGroup;
    }

    public static void main(String[] args) {
        System.out.println("-- 本周第一天 --");
        System.out.println(DateUtil.getFirstOfWeek("2018-03-08", "yyyy-MM-dd"));
        System.out.println("-- 本周最后一天 --");
        System.out.println(DateUtil.getLastOfWeek("2018-01-12", "yyyy-MM-dd"));
        System.out.println("-- 某月天数 --");
        System.out.println(DateUtil.getLengthOfMonth("2018-01-12", "yyyy-MM-dd"));
        System.out.println("-- 某年天数 --");
        System.out.println(DateUtil.getLengthOfYear("2018-01-12", "yyyy-MM-dd"));
        System.out.println("-- 分页开始日期 --");
        System.out.println(DateUtil.getStartDateWithPage(2, 5, "yyyy-MM-dd"));
        System.out.println("-- 分页结束日期 --");
        System.out.println(DateUtil.getEndDateWithPage(2, 5, "yyyy-MM-dd"));
        System.out.println("-- 分页开始日期时间 --");
        System.out.println(DateUtil.getStartDateTimeWithPage(2, 5, "yyyy-MM-dd HH:mm:ss"));
        System.out.println("-- 分页结束日期时间 --");
        System.out.println(DateUtil.getEndDateTimeWithPage(2, 5, "yyyy-MM-dd HH:mm:ss"));
        System.out.println("-- 按小时分组 --");
        List<String> hourGroup = DateUtil.getHourGroup(3, " - ", "HH:mm:ss");
        hourGroup.forEach(h -> System.out.println(h));
        System.out.println("-- 按天分组 --");
        List<String> dayGroup = DateUtil.getDayGroup(7, " - ", "2018-01-01", "2018-01-11", "yyyy-MM-dd");
        dayGroup.forEach(d -> System.out.println(d));
        System.out.println("-- 按月分组 --");
        List<String> monthGroup = DateUtil.getMonthGroup(2, " - ", "2018-01-03", "2018-05-05", "yyyy-MM-dd");
        monthGroup.forEach(m -> System.out.println(m));
    }

    /**
     * 时间字符串转Timestamp
     * created by kangu on 2018/01/25
     *
     * @param str
     * @return
     */
    public static Timestamp strToTimestamp(String str) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        try {
            Date date = sf.parse(str);
            Timestamp t1 = new Timestamp(date.getTime());
            System.out.println("strToTimestamp: " + t1);
            return t1;
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 通过Asia/Shanghai时区来获取当前时间（解决时区滞后8小时的问题）
     * created by kangu on 2018/02/07
     *
     * @return
     */
    public static Timestamp getCurrentTimeByZone() {
        TimeZone timeZone = TimeZone.getTimeZone("GMT+8:00");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        simpleDateFormat.setTimeZone(timeZone);
        String now = simpleDateFormat.format(new Date());
        return strToTimestamp(now);
    }

}
